package learning.spring.binarytea;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.web.servlet.mvc.UrlFilenameViewController;

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService userDetailsService(ObjectProvider<PasswordEncoder> passwordEncoder) {
        // 首先从Spring上下文中获取Encoder，如果没有创建一个
        PasswordEncoder encoder = passwordEncoder.getIfAvailable(PasswordEncoderFactories::createDelegatingPasswordEncoder);

        // 新建一个用户
        UserDetails employee = User.builder()
                .username("lilei")
                .password("binarytea")
                .authorities("READ_ORDER", "WRITE_ORDER")
                .passwordEncoder(encoder::encode)// 密码加密
                .build();

        // InMemoryUserDetailsManager(UserDetails... users) 可接受多个UserDetails对象传参
        // 用户信息存储在内存管理器中
        return new InMemoryUserDetailsManager(employee);
    }

    @Bean("/login")
    public UrlFilenameViewController loginController() {
        UrlFilenameViewController controller = new UrlFilenameViewController();
        controller.setSupportedMethods(HttpMethod.GET.name());
        controller.setSuffix(".html");
        return controller;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .mvcMatchers("/actuator/*").permitAll()
                .anyRequest().authenticated().and()
                .formLogin()
                .loginPage("/login").permitAll()
                .defaultSuccessUrl("/order")
                .failureUrl("/login")
                .loginProcessingUrl("/doLogin")
                .usernameParameter("user")
                .passwordParameter("pwd").and()
                .httpBasic();
    }

}
